home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / Method.java < prev    next >
Text File  |  1998-09-22  |  10KB  |  279 lines

  1. /*
  2.  * @(#)Method.java    1.15 98/07/01
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.lang.reflect;
  16.  
  17. /**
  18.  * A Method provides information about, and access to, a single method
  19.  * on a class or interface.  The reflected method may be a class method
  20.  * or an instance method (including an abstract method).
  21.  *
  22.  * <p>A Method permits widening conversions to occur when matching the
  23.  * actual parameters to invokewith the underlying method's formal
  24.  * parameters, but it throws an IllegalArgumentException if a
  25.  * narrowing conversion would occur.
  26.  *
  27.  * @see Member
  28.  * @see java.lang.Class
  29.  * @see java.lang.Class#getMethods()
  30.  * @see java.lang.Class#getMethod()
  31.  * @see java.lang.Class#getDeclaredMethods()
  32.  * @see java.lang.Class#getDeclaredMethod()
  33.  *
  34.  * @author Nakul Saraiya
  35.  */
  36. public final
  37. class Method implements Member {
  38.  
  39.     private Class        clazz;
  40.     private int            slot;
  41.     private String        name;
  42.     private Class        returnType;
  43.     private Class[]        parameterTypes;
  44.     private Class[]        exceptionTypes;
  45.  
  46.     /**
  47.      * Constructor.  Only the Java Virtual Machine may construct a Method.
  48.      */
  49.     private Method() {}
  50.  
  51.     /**
  52.      * Returns the Class object representing the class or interface
  53.      * that declares the method represented by this Method object.
  54.      */
  55.     public Class getDeclaringClass() {
  56.     return clazz;
  57.     }
  58.  
  59.     /**
  60.      * Returns the name of the method represented by this Method
  61.      * object, as a String.
  62.      */
  63.     public String getName() {
  64.     return name;
  65.     }
  66.  
  67.     /**
  68.      * Returns the Java language modifiers for the method represented
  69.      * by this Method object, as an integer. The Modifier class should
  70.      * be used to decode the modifiers.
  71.      *
  72.      * @see Modifier
  73.      */
  74.     public native int getModifiers();
  75.  
  76.     /**
  77.      * Returns a Class object that represents the formal return type
  78.      * of the method represented by this Method object.
  79.      */
  80.     public Class getReturnType() {
  81.     return returnType;
  82.     }
  83.  
  84.     /**
  85.      * Returns an array of Class objects that represent the formal
  86.      * parameter types, in declaration order, of the method
  87.      * represented by this Method object.  Returns an array of length
  88.      * 0 if the underlying method takes no parameters.
  89.      */
  90.     public Class[] getParameterTypes() {
  91.     return copy(parameterTypes);
  92.     }
  93.  
  94.     /**
  95.      * Returns an array of Class objects that represent the types of
  96.      * the checked exceptions thrown by the underlying method
  97.      * represented by this Method object.  Returns an array of length
  98.      * 0 if the method throws no checked exceptions.
  99.      */
  100.     public Class[] getExceptionTypes() {
  101.     return copy(exceptionTypes);
  102.     }
  103.  
  104.     /**
  105.      * Compares this Method against the specified object.  Returns
  106.      * true if the objects are the same.  Two Methods are the same if
  107.      * they were declared by the same class and have the same name
  108.      * and formal parameter types.
  109.      */
  110.     public boolean equals(Object obj) {
  111.     if (obj != null && obj instanceof Method) {
  112.         Method other = (Method)obj;
  113.         if ((getDeclaringClass() == other.getDeclaringClass())
  114.         && (getName().equals(other.getName()))) {
  115.         /* Avoid unnecessary cloning */
  116.         Class[] params1 = parameterTypes;
  117.         Class[] params2 = other.parameterTypes;
  118.         if (params1.length == params2.length) {
  119.             for (int i = 0; i < params1.length; i++) {
  120.             if (params1[i] != params2[i])
  121.                 return false;
  122.             }
  123.             return true;
  124.         }
  125.         }
  126.     }
  127.     return false;
  128.     }
  129.  
  130.     /**
  131.      * Returns a hashcode for this Method.  The hashcode is computed
  132.      * as the exclusive-or of the hashcodes for the underlying
  133.      * method's declaring class name and the method's name.
  134.      */
  135.     public int hashCode() {
  136.     return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
  137.     }
  138.  
  139.     /**
  140.      * Returns a string describing this Method.  The string is
  141.      * formatted as the method access modifiers, if any, followed by
  142.      * the method return type, followed by a space, followed by the
  143.      * class declaring the method, followed by a period, followed by
  144.      * the method name, followed by a parenthesized, comma-separated
  145.      * list of the method's formal parameter types. If the method
  146.      * throws checked exceptions, the parameter list is followed by a
  147.      * space, followed by the word throws followed by a
  148.      * comma-separated list of the thrown exception types.
  149.      * For example:
  150.      * <pre>
  151.      *    public boolean java.lang.Object.equals(java.lang.Object)
  152.      * </pre>
  153.      *
  154.      * <p>The access modifiers are placed in canonical order as
  155.      * specified by "The Java Language Specification".  This is
  156.      * <tt>public</tt>, <tt>protected</tt> or <tt>private</tt> first,
  157.      * and then other modifiers in the following order:
  158.      * <tt>abstract</tt>, <tt>static</tt>, <tt>final</tt>,
  159.      * <tt>synchronized</tt> <tt>native</tt>.
  160.      */
  161.     public String toString() {
  162.     try {
  163.         StringBuffer sb = new StringBuffer();
  164.         int mod = getModifiers();
  165.         if (mod != 0) {
  166.         sb.append(Modifier.toString(mod) + " ");
  167.         }
  168.         sb.append(Field.getTypeName(getReturnType()) + " ");
  169.         sb.append(Field.getTypeName(getDeclaringClass()) + ".");
  170.         sb.append(getName() + "(");
  171.         Class[] params = parameterTypes; // avoid clone
  172.         for (int j = 0; j < params.length; j++) {
  173.         sb.append(Field.getTypeName(params[j]));
  174.         if (j < (params.length - 1))
  175.             sb.append(",");
  176.         }
  177.         sb.append(")");
  178.         Class[] exceptions = exceptionTypes; // avoid clone
  179.         if (exceptions.length > 0) {
  180.         sb.append(" throws ");
  181.         for (int k = 0; k < exceptions.length; k++) {
  182.             sb.append(exceptions[k].getName());
  183.             if (k < (exceptions.length - 1))
  184.             sb.append(",");
  185.         }
  186.         }
  187.         return sb.toString();
  188.     } catch (Exception e) {
  189.         return "<" + e + ">";
  190.     }
  191.     }
  192.  
  193.     /**
  194.      * Invokes the underlying method represented by this Method
  195.      * object, on the specified object with the specified parameters.
  196.      * Individual parameters are automatically unwrapped to match
  197.      * primitive formal parameters, and both primitive and reference
  198.      * parameters are subject to widening conversions as
  199.      * necessary. The value returned by the underlying method is
  200.      * automatically wrapped in an object if it has a primitive type.
  201.      *
  202.      * <p>Method invocation proceeds with the following steps, in order:
  203.      *
  204.      * <p>If the underlying method is static, then the specified object
  205.      * argument is ignored. It may be null.
  206.      *
  207.      * <p>Otherwise, the method is an instance method.  If the specified
  208.      * object argument is null, the invocation throws a
  209.      * NullPointerException.  Otherwise, if the specified object
  210.      * argument is not an instance of the class or interface declaring
  211.      * the underlying method, the invocation throws an
  212.      * IllegalArgumentException.
  213.      *
  214.      * <p>If this Method object enforces Java language access control and
  215.      * the underlying method is inaccessible, the invocation throws an
  216.      * IllegalAccessException.
  217.      *
  218.      * <p>If the number of actual parameters supplied via args is
  219.      * different from the number of formal parameters required by the
  220.      * underlying method, the invocation throws an
  221.      * IllegalArgumentException.
  222.      *
  223.      * <p>For each actual parameter in the supplied args array:
  224.      *
  225.      * <p>If the corresponding formal parameter has a primitive type, an
  226.      * unwrapping conversion is attempted to convert the object value
  227.      * to a value of a primitive type.  If this attempt fails, the
  228.      * invocation throws an IllegalArgumentException.
  229.      *
  230.      * <p>If, after possible unwrapping, the parameter value cannot be
  231.      * converted to the corresponding formal parameter type by an
  232.      * identity or widening conversion, the invocation throws an
  233.      * IllegalArgumentException.
  234.      *
  235.      * <p>If the underlying method is an instance method, it is invoked
  236.      * using dynamic method lookup as documented in The Java Language
  237.      * Specification, section 15.11.4.4; in particular, overriding
  238.      * based on the runtime type of the target object will occur.
  239.      *
  240.      * <p>If the underlying method is static, it is invoked as exactly
  241.      * the method on the declaring class.
  242.      *
  243.      * <p>Control transfers to the underlying method.  If the method
  244.      * completes abruptly by throwing an exception, the exception is
  245.      * placed in an InvocationTargetException and thrown in turn to
  246.      * the caller of invoke.
  247.      *
  248.      * <p>If the method completes normally, the value it returns is
  249.      * returned to the caller of invoke; if the value has a primitive
  250.      * type, it is first appropriately wrapped in an object. If the
  251.      * underlying method return type is void, the invocation returns
  252.      * null.
  253.      *
  254.      * @exception IllegalAccessException    if the underlying method
  255.      *              is inaccessible.
  256.      * @exception IllegalArgumentException  if the number of actual and formal
  257.      *              parameters differ, or if an unwrapping conversion fails.
  258.      * @exception InvocationTargetException if the underlying method
  259.      *              throws an exception.
  260.      * @exception NullPointerException      if the specified object is null.
  261.      */
  262.     public native Object invoke(Object obj, Object[] args)
  263.     throws IllegalAccessException, IllegalArgumentException,
  264.         InvocationTargetException;
  265.  
  266.     /*
  267.      * Avoid clone()
  268.      */
  269.     static Class[] copy(Class[] in) {
  270.     int l = in.length;
  271.     if (l == 0)
  272.         return in;
  273.     Class[] out = new Class[l];
  274.     for (int i = 0; i < l; i++)
  275.         out[i] = in[i];
  276.     return out;
  277.     }
  278. }
  279.